#pragma once

#include <list>
#include <set>
#include "Pointer.h"
#include "Vector3D.h"
#include "Quaternion.h"
#include "Subject.h"
#include "IShape.h"
#include "btBulletDynamicsCommon.h"

class System;

class RigidBody
{
public:
	typedef std::list<RigidBody*> List_t;
	typedef std::set<Pointer<RigidBody>> Set_t;
	typedef bool(*CallbackFunction)(const Pointer<RigidBody>& thisbody, const Pointer<RigidBody>& otherBody);
	
	RigidBody( float mass = 0.0f, void* userPointer = 0, Maths::Vector3D& position = Maths::Vector3D(), Maths::Vector3D& rotation = Maths::Vector3D());
	~RigidBody();

	void Initialize( float mass, Maths::Vector3D& position, Maths::Vector3D& rotation, void* userPointer );
	void Deinitialize();

	Subject<Maths::Vector3D>& getPosition();
	Subject<Maths::Quaternion>& getRotation();

	Pointer<btRigidBody>& getRigidBody();
	void AddShape( Pointer<IShape>& collisionShape );
	void ClearShapes();
	void RemoveShape( unsigned int index );
	std::vector<Pointer<IShape>>& getShapes();
	System* getSystem();

	void setSystem( System* system );
	void setRotation( Maths::Quaternion& rotation );
	void setPosition( const Maths::Vector3D& position );
	void setMass( float mass );

	void SetStatic();
	void Accelerate(Maths::Vector3D& linearVelocity);
protected:
	Subject<Maths::Vector3D> m_position;
	Subject<Maths::Quaternion> m_rotation;

	Pointer<btCompoundShape> m_shape;
	std::vector<Pointer<IShape>> m_childShapes;
	Pointer<btRigidBody> m_rigidBody;
	Pointer<btMotionState> m_motionState;

	float m_mass;

	System* m_system;
};